#include "bhxjwaveshader.h"

BHXJWaveShader::BHXJWaveShader(QWidget *parent) : QOpenGLWidget(parent)
{
    QSurfaceFormat surfaceFormat(this->format());
    surfaceFormat.setDepthBufferSize(0);   //不使用深度缓存
    surfaceFormat.setStencilBufferSize(0); //
    surfaceFormat.setSamples(4);
    setFormat(surfaceFormat);

    void (BHXJWaveShader::*fun)()=&BHXJWaveShader::update;
    connect(this,&BHXJWaveShader::Refrush,this,fun,Qt::QueuedConnection);
    connect(this,&BHXJWaveShader::RefrushMask,this,&BHXJWaveShader::updateMask,Qt::QueuedConnection);

    timer=new QTimer(this);
    timer->setInterval(20);
    connect(timer,&QTimer::timeout,this,&BHXJWaveShader::timeoutfun);
    timer->start();
}
void BHXJWaveShader::initializeGL()
{
    initializeOpenGLFunctions();
    float vertices[] = {
        //---- 位置 ----     - 纹理坐标 -
        1.0f,  1.0f,       1.0f, 1.0f,     // 右上
        1.0f, -1.0f,       1.0f, 0.0f,     // 右下
        -1.0f, -1.0f,      0.0f, 0.0f,     // 左下
        -1.0f,  1.0f,      0.0f, 1.0f      // 左上
    };
    unsigned int indices[] = { // 注意索引从0开始!
        3, 1, 0, // 第一个三角形
        3, 2, 1  // 第二个三角形
    };
    glGenVertexArrays(1,&VAO);
    glGenBuffers(1,&VBO);
    glGenBuffers(1,&EBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);

    glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,4*sizeof(float),nullptr);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,4*sizeof(float),reinterpret_cast<void*>(2*sizeof(float)));
    glEnableVertexAttribArray(1);


    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

    myshader.Init(this,":/wavesin/2dvertexshader.vert",":/wavesin/wavesinfragmentshader.frag");

    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);
}
void BHXJWaveShader::paintGL()
{
    if(this->width()<=0||this->height()<=0)
        return;
    if(this->_BeEllipse)
    {    QRegion qr(0,0,this->width(),this->height(),QRegion::Ellipse);
        this->setMask(qr);
    }
    else
    {
        this->clearMask();
    }

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    myshader.use();
    QColor bc(this->palette().background().color());
    myshader.setVec4("BackColor",glm::vec4(bc.red()/255.0f,
                                            bc.green()/255.0f,
                                            bc.blue()/255.0f,
                                            bc.alpha()/255.0f));
    myshader.setVec4("WaterColor",glm::vec4(_WaveColor.red()/255.0f,
                                             _WaveColor.green()/255.0f,
                                             _WaveColor.blue()/255.0f,
                                             _WaveColor.alpha()/255.0f));
    myshader.setFloat("Offset",static_cast<float>(offset));
    myshader.setFloat("PasheDiffent",static_cast<float>(_PhaseDifference));
    myshader.setFloat("WaveHeight",static_cast<float>(_WaveHeight));
    myshader.setFloat("PixelHeight",this->height());
    myshader.setFloat("WaveDensity",static_cast<float>(_WaveDensity));
     myshader.setFloat("Value",static_cast<float>(_Value));

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);


    glBindVertexArray(VAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
    //glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, reinterpret_cast<void*>(0));
    glBindVertexArray(0);

    QPainter painter;
    painter.begin(this);
    painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);
    if(this->BeEllipse())
    {
        painter.setBrush(Qt::NoBrush);
        painter.setPen(QPen(_FrameColor,2));
        painter.drawEllipse(0,0,this->width(),this->height());
    }

    QFont mfont(this->font());
    mfont.setPointSizeF((this->width()>this->height()?this->height():this->width())/6);
    QFontMetrics metric(mfont);
    painter.setPen(QPen(this->palette().text().color()));
    QString str=QString::number(static_cast<int>(_Value*100.+0.01));
    str.append("%");
    QRect boundingRect = metric.boundingRect(str);
    painter.setFont(mfont);
    painter.drawText(QPointF(this->width()/2-boundingRect.width()/2,this->height()*0.5+boundingRect.height()*0.3),str);
    painter.end();
}
//void BHXJWaveShader::resizeGL(int width, int height)
//{

//}

void BHXJWaveShader::timeoutfun()
{
    this->offset+=_WaveDensity*_Speed*0.02;
    int n=static_cast<int>(this->offset);
    this->offset-=n;
    this->update();
}
void BHXJWaveShader::updateMask()
{
    if(this->_BeEllipse)
    {    QRegion qr(0,0,this->width(),this->height(),QRegion::Ellipse);
        this->setMask(qr);
    }
    else
    {
        this->clearMask();
    }
    this->update();
}
